package com.sxpi.zixun.config.mvc;

import com.sxpi.zixun.config.interceptor.PassportLoginInterceptor;
import com.sxpi.zixun.config.interceptor.PassportLogoutInterceptor;
import org.passay.MessageResolver;
import org.passay.spring.SpringMessageResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

/**
 * @Author: 董伟豪
 * @Date: 2022/6/10 15:56
 */
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    /**
     * 登录拦截器
     */
    @Autowired
    private PassportLoginInterceptor passportLoginInterceptor;

    /**
     * 下线拦截器
     */
    @Autowired
    private PassportLogoutInterceptor passportLogoutInterceptor;

    @Value("${file.staticPatternPath}")
    private String staticPatternPath;

    @Value("${file.uploadFolder}")
    private String uploadFolder;

    /**
     * 拦截全部接口，除却登录功能
     * 先判断下线，后判断登录
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(passportLogoutInterceptor).addPathPatterns("/admin/**")
                .excludePathPatterns("/admin/login/**","/admin/captcha");
        registry.addInterceptor(passportLoginInterceptor).addPathPatterns("/admin/**")
                .excludePathPatterns("/admin/login/**","/admin/captcha");
    }

    /**
     * 默认解析器 其中locale表示默认语言
     * http://127.0.0.1:8877/admin/banner/saveupdate?lang=en_US
     * http://127.0.0.1:8877/admin/banner/saveupdate?lang=zh_CN
     *
     */
    @Bean
    public LocaleResolver localeResolver() {
        return new MyLocaleResolver();
    }

    /**
     * 配置国际化文件的存储目录和前缀
     * 这里也可以在配置文件(application.yml)中写
     * messageSource()不能随意更改，因为如果和MessageSourceAutoConfiguration中的名字不一样的话，就无法去覆盖springboot里面的值了
     * 当然加上@Primary注解也是可以的
     * @return
     */
    @Bean
    public MessageSource messageSource()  {
        ResourceBundleMessageSource rbms = new ResourceBundleMessageSource();
        rbms.setDefaultEncoding("UTF-8");
        rbms.setBasenames("i18n/messages");
        return rbms;
    }

    /**
     * 语言切换
     * 拦截器的作用就是为了让你去设定语言后缀参数
     *  http://127.0.0.1:8877/admin/banner/saveupdate?lang=en_US
     *  http://127.0.0.1:8877/admin/banner/saveupdate?lang=zh_CN
     * @return
     */
    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
        localeChangeInterceptor.setParamName("lang");
        return localeChangeInterceptor;
    }

    /**
     * ----把验证框架和国际化进行捆绑----
     * 配置 Java Validation 使用国际化的消息资源
     * @return LocalValidatorFactoryBean
     */
    @Bean
    @Override
    public LocalValidatorFactoryBean getValidator() {
        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
        bean.setValidationMessageSource(messageSource());
        return bean;
    }

    /**
     * ----把验证框架和国际化进行捆绑----
     * 这个主要是和 PasswordConstraintValidator类绑定，如果PasswordConstraintValidator不存在，那么这个完全可以不用写
     * 密码和确定密码的那个类
     * 配置 Passay 使用 Spring 的 MessageSource
     * @return MessageResolver
     */
    @Bean
    public MessageResolver messageResolver() {
        return new SpringMessageResolver(messageSource());
    }

    /**
     * 静态资源的访问位置
     * 位置的映射，只要是访问 staticPatterPath 下面的目录就会自动取 uploadFolder 中取寻找
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(staticPatternPath).addResourceLocations("file:" + uploadFolder);
    }

}
